Skip to content

feat(agents): restrict session ingestion to CodeMie-owned sessions#403

Open
BolotnyaBoss wants to merge 12 commits into
codemie-ai:mainfrom
BolotnyaBoss:EPMCDME-12992
Open

feat(agents): restrict session ingestion to CodeMie-owned sessions#403
BolotnyaBoss wants to merge 12 commits into
codemie-ai:mainfrom
BolotnyaBoss:EPMCDME-12992

Conversation

@BolotnyaBoss

Copy link
Copy Markdown
Contributor

Summary

Implements EPMCDME-12992. CodeMie was ingesting all Claude sessions from ~/.claude/projects/ without verifying ownership, causing unrelated sessions to appear in Analytics and allowing codemie-claude --resume to silently ingest external sessions. This PR adds session origin validation across the full ingestion and resume path.

Changes

Core ownership check

  • session-origin-audit.ts — writes a sidecar marker file ~/.codemie/sessions/{id}-codemie-marker.json at session start and appends events to ~/.codemie/logs/session-origin-audit.jsonl
  • session-ownership.tsscanSessionsForClaudeId() scans correlation records in ~/.codemie/sessions/ to determine ownership

Resume validation (AgentCLI.ts)

  • Validates --resume target against ownership index before proceeding
  • External sessions: interactive prompt with y/N; non-interactive mode blocks silently
  • Confirmed external resumes: CODEMIE_CONV_SYNC_DISABLED=1 injected into subprocess env and current process env to suppress conversation sync
  • Slug-based resume fixed: removed UUID regex that blocked codemie-claude --resume epmcdme-12992

Analytics (native-loader.ts, formatter.ts)

  • Dual-signal ownership index: correlation records + sidecar markers
  • External (non-CodeMie) native sessions labeled native-external, displayed with yellow native [external ⚠ not CodeMie-managed] in terminal output
  • Filter precision: !f.endsWith('_metrics.json') (was !f.includes('_metrics'))

Conv sync guards (codex/gemini/opencode processors)

  • shouldProcess() returns false when CODEMIE_CONV_SYNC_DISABLED=1

Testing

  • Unit and integration tests added (native-loader.test.ts, syncProcessor-guard.test.ts)
  • All existing tests pass — 148 unit files, 2194 passed; 27 integration files, 220 passed
  • Manual testing: owned session resume (no prompt), external session resume (prompt shown), slug-based resume (no crash), audit log written
  • Lint: 0 errors, 0 warnings
  • TypeScript: no diagnostics
  • Build: clean

Checklist

  • Code follows project standards
  • No secrets or unsafe logging introduced
  • Architecture boundaries respected (CLI → agent layer only)
  • CI green — pending after merge (local gates passed)
  • No merge conflicts with main — rebase before merge if needed

Closes EPMCDME-12992

Sviatoslav Likhtarchyk and others added 12 commits July 1, 2026 11:28
- Fix _metrics.json filter in session-ownership: use endsWith instead of
  includes to avoid skipping legitimate session files whose names merely
  contain the substring _metrics
- Guard ConversationsProcessor.shouldProcess against CODEMIE_CONV_SYNC_DISABLED
  to prevent writing PENDING payloads for external resume sessions
- Extract shouldBlockNonInteractiveResume as module-level export from AgentCLI
  so the non-TTY/no-prompts path can be unit-tested without mocking private
  state; refactor promptExternalResume to delegate to it
- Add tests for shouldBlockNonInteractiveResume and the _metrics filter fix

Generated with AI

Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
…dation

- Remove UUID_RE guard that rejected non-UUID --resume values (e.g. ticket
  slugs like epmcdme-12992); sanitize resumeId for display with \p{Cc}/gu
- Also set process.env.CODEMIE_CONV_SYNC_DISABLED in parent process so
  same-process conversation sync consumers respect the suppression flag;
  clean up after adapter.run() completes
- Standardize _metrics file filter to endsWith('_metrics.json') in
  native-loader.ts, consistent with session-ownership.ts
- Write sidecar marker in session-origin-audit.ts and add existsSync guard
  before transcript append (non-fatal, race-condition-free ownership signal)
- Add CODEMIE_CONV_SYNC_DISABLED guard to codex, gemini, opencode
  conversation processors

Generated with AI

Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Work item, spec, plan, two code-review verdicts, task state,
gate plan, and QA report for session origin validation.

Generated with AI

Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Generated with AI

Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
…ons in HTML report

- HTML report now renders an amber warning badge in both the sessions
  table ("⚠ ext" tag) and the session-detail modal header
  ("⚠ external — not CodeMie-managed") when session.provider is
  "native-external". Previously the sessions were silently shown with
  no visual distinction from CodeMie-owned sessions.
- Fix pre-existing crash in AnalyticsAggregator.deriveTitle: guard
  against prompt.text being a non-string value (e.g. content-block
  array) to prevent "raw.replace is not a function" TypeErrors that
  blocked HTML report generation.

Generated with AI

Co-Authored-By: codemie-ai <codemie.ai@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant